﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.IO;
using System.Threading;
namespace UcAsp.Net.ModelCreate
{
    public partial class Create : Form
    {
        private List<string> list=new List<string>();
         private static string Path
        {
            get { return AppDomain.CurrentDomain.BaseDirectory + "\\Models\\"; }
        }
        public Create()
        {
            InitializeComponent();
            if (!Directory.Exists(Path))
            {
                Directory.CreateDirectory(Path);
            }
            foreach (string d in Directory.GetFiles(Path))
            {
                File.Delete(d);
            }
            
            
        }

        private void button1_Click(object sender, EventArgs e)
        {
            foreach (string d in Directory.GetFiles(Path))
            {
                File.Delete(d);
            }
            string Sql = @"SELECT 
                            TableNames=CASE WHEN C.column_id=1 THEN O.name ELSE N'' END,
                            CoumnNames=C.name,
                            IndesName=ISNULL(IDX.PrimaryKey,N''),
    
                            --Computed=CASE WHEN C.is_computed=1 THEN N'√'ELSE N'' END,
                            TypeNames=T.name,
    

                            ISNULLABLE=CASE WHEN C.is_nullable=1 THEN N'√'ELSE N'' END,
    
                            DisPlayNames=ISNULL(PFD.[value],N''),
	                        Length=C.max_length,
                            Precision=C.precision
                            --[IDENTITY]=CASE WHEN C.is_identity=1 THEN N'√'ELSE N'' END
    
                        FROM sys.columns C
                            INNER JOIN sys.objects O
                                ON C.[object_id]=O.[object_id]
                                    AND O.type='U'
                                    AND O.is_ms_shipped=0
                            INNER JOIN sys.types T
                                ON C.user_type_id=T.user_type_id
                            LEFT JOIN sys.default_constraints D
                                ON C.[object_id]=D.parent_object_id
                                    AND C.column_id=D.parent_column_id
                                    AND C.default_object_id=D.[object_id]
                            LEFT JOIN sys.extended_properties PFD
                                ON PFD.class=1 
                                    AND C.[object_id]=PFD.major_id 
                                    AND C.column_id=PFD.minor_id
                        --             AND PFD.name='Caption'  -- 字段说明对应的描述名称(一个字段可以添加多个不同name的描述)
                            LEFT JOIN sys.extended_properties PTB
                                ON PTB.class=1 
                                    AND PTB.minor_id=0 
                                    AND C.[object_id]=PTB.major_id
                        --             AND PFD.name='Caption'  -- 表说明对应的描述名称(一个表可以添加多个不同name的描述) 
                            LEFT JOIN                       -- 索引及主键信息
                            (
                                SELECT 
                                    IDXC.[object_id],
                                    IDXC.column_id,
                                    Sort=CASE INDEXKEY_PROPERTY(IDXC.[object_id],IDXC.index_id,IDXC.index_column_id,'IsDescending')
                                        WHEN 1 THEN 'DESC' WHEN 0 THEN 'ASC' ELSE '' END,
                                    PrimaryKey=CASE WHEN IDX.is_primary_key=1 THEN N'√'ELSE N'' END,
                                    IndexName=IDX.Name
                                FROM sys.indexes IDX
                                INNER JOIN sys.index_columns IDXC
                                    ON IDX.[object_id]=IDXC.[object_id]
                                        AND IDX.index_id=IDXC.index_id
                                LEFT JOIN sys.key_constraints KC
                                    ON IDX.[object_id]=KC.[parent_object_id]
                                        AND IDX.index_id=KC.unique_index_id
                                INNER JOIN  -- 对于一个列包含多个索引的情况,只显示第1个索引信息
                                (
                                    SELECT [object_id], Column_id, index_id=MIN(index_id)
                                    FROM sys.index_columns
                                    GROUP BY [object_id], Column_id
                                ) IDXCUQ
                                    ON IDXC.[object_id]=IDXCUQ.[object_id]
                                        AND IDXC.Column_id=IDXCUQ.Column_id
                                        AND IDXC.index_id=IDXCUQ.index_id
                            ) IDX
                                ON C.[object_id]=IDX.[object_id]
                                    AND C.column_id=IDX.column_id 
                        WHERE O.name= ";
            DataBase data = new DataBase(SqlConnention.Text);
           SqlDataReader rd= data.ExecuteReader(Sql);
            
           while (rd.Read())
           { 
               
               if (list.Count==0)
               {

                   list.Add(rd.GetString(0));
               }
               else
               {
                   if (list[list.Count-1] != rd.GetString(0))
                   {
                       list.Add(rd.GetString(0));
                   }
               }

               creatModel(rd.GetString(0), rd.GetString(1), rd.GetString(2), rd.GetString(3), rd.GetString(4), rd.GetString(5));
              
            
           }
           Thread.Sleep(1000);
           for (int i = 0; i < list.Count; i++)
           {
               string file = list[i] + ".cs";
               StreamWriter app = File.AppendText(Path + "/" + file);
               app.WriteLine("         } ");
               app.WriteLine("} ");
               app.Flush();
               app.Close();
               app.Dispose();
              // MessageBox.Show(file);
               if (!File.Exists(Path + "/" + Entities.Text+"Entities.cs"))
               {
                   StreamWriter sw = File.CreateText(Path + "/" + Entities.Text + "Entities.cs");
                   sw.Flush();
                   sw.Close();
                   sw.Dispose();
                   StreamWriter entities = File.AppendText(Path + "/" + Entities.Text + "Entities.cs");
                   entities.WriteLine("using System;");
                   entities.WriteLine("using System.Data.Entity;");
                   entities.WriteLine("namespace " +ClassNames.Text);
                   entities.WriteLine("{");
                   entities.WriteLine("      public class "+Entities.Text+"Entities:DbContext");
                   entities.WriteLine("         {");
                   entities.WriteLine("             public DbSet<" + list[i] + "> " + list[i] + "s { get; set; }");
                   entities.Flush();
                   entities.Close();
                   entities.Dispose();                


               }
               else
               {
                   StreamWriter entities = File.AppendText(Path + "/" + Entities.Text + "Entities.cs");
                   entities.WriteLine("             public DbSet<" + list[i] + "> " + list[i] + "s { get; set; }");
                   entities.Flush();
                   entities.Close();
                   entities.Dispose();
               }

           }
           StreamWriter end = File.AppendText(Path + "/" + Entities.Text+"Entities.cs");
           end.WriteLine("       }");
           end.WriteLine("}");
           end.Flush();
           end.Close();
           end.Dispose();
           MessageBox.Show("生成完成！");
        }

        private void creatModel(string tablename,string name,string indexname,string typename,string isnullable,string displayname)
        { 
            string file = tablename + ".cs";
            if (!File.Exists(Path + "/" + file))
                {
                    StreamWriter sw = File.CreateText(Path + "/" + file);
                    sw.Flush();
                    sw.Close();
                    sw.Dispose();
                    StreamWriter header = File.AppendText(Path + "/" + file);
                    header.WriteLine("using System;");
                    header.WriteLine("using System.ComponentModel;");
                    header.WriteLine("using System.ComponentModel.DataAnnotations;");
                    header.WriteLine("using System.Collections;");
                    header.WriteLine("using System.Collections.Generic;");
                    header.WriteLine("namespace " +ClassNames.Text);
                    header.WriteLine("{");
                    header.WriteLine("      [Table(\"" + tablename + "\")]");
                    header.WriteLine("      public class " + tablename + "");
                    header.WriteLine("      {");
                    header.Flush();
                    header.Close();
                    header.Dispose();


                }
                    StreamWriter app = File.AppendText(Path + "/" + file);

                    if (indexname == "True")
                    {
                        app.WriteLine("         [Key]  ");
                    }
                    if (isnullable == "False" && indexname=="False")
                    {
                        app.WriteLine("         [Required(ErrorMessage = \"" + displayname + "不能空\")]  ");
                    }
                    
                    app.WriteLine("         [DisplayName(\"" + displayname + "\")] ");
                    List<Property> list=Sql2Csharp.List();
                    Property cp=list.Find(c => c.SqlType == typename);
                    app.WriteLine("         public " + cp.CsharpType + " " + name + " { get; set; }");
                    app.Flush();
                    app.Close();
                    app.Dispose();
                
        }
    }
}
